home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1999 April / macformat-075.iso / Shareware Plus / Applications / Alpha / Tcl / Menus / electricMenu.tcl < prev    next >
Encoding:
Text File  |  1999-01-31  |  11.2 KB  |  351 lines  |  [TEXT/ALFA]

  1. ## -*-Tcl-*-
  2.  # ###################################################################
  3.  #    Vince's    Additions -    an extension package for Alpha
  4.  # 
  5.  #    FILE: "electricMenu.tcl"
  6.  #                     created: 8/3/96 {1:34:42 pm}    
  7.  #                  last update: 31/1/1999 {11:22:18 pm}    
  8.  #    Author:    Vince Darley
  9.  #    E-mail:    <darley@fas.harvard.edu>
  10.  #      mail:    Division of    Applied    Sciences, Harvard University
  11.  #            Oxford Street, Cambridge MA    02138, USA
  12.  #       www:    <http://www.fas.harvard.edu/~darley/>
  13.  #    
  14.  #    Handles the electric menu.
  15.  #    
  16.  # ###################################################################
  17.  ##
  18.  
  19. alpha::menu electricMenu 1.3.3 global "•280" {
  20.     # so we don't use the standard proc to build this menu.
  21.     menu::buildProc elec "#"
  22.     namespace eval elec {}
  23. } { 
  24.     elec::rebuildElectricMenu 
  25. } {
  26. } maintainer {
  27.     "Vince Darley" darley@fas.harvard.edu <http://www.fas.harvard.edu/~darley/>
  28. } uninstall this-file help {file "ElecCompletions Help"}
  29.  
  30. alpha::package require elecCompletions 9.0
  31.  
  32. lunion flagPrefs(Electrics) showElectricsInMenu putTemplatesInMainMenu \
  33.   showElectricKeysInMenu addTemplateManipulators 
  34.  
  35. eval lunion elec::MenuTemplates ""
  36. lunion elec::LicenseTemplates \
  37.   "none" "copyrightNotice" "allRightsReserved" "allRightsReservedOrg" \
  38.   "seeFileLicenseTerms" "gnuPublicLicense"
  39.  
  40. # register this proc to be called whenever the mode changes.
  41. hook::register changeMode elec::rebuildElectricMenu
  42. hook::register electricBindings elec::BindingsChanged
  43. # To show mode-dependent electric completions in menu; i.e. include in the
  44. # menu all items which when typed, followed by cmd-Tab, will complete
  45. # into some command, click this box||To remove all mode-dependent
  46. # completions from the electric menu, once you've learnt everything that's
  47. # available, click this box.
  48. newPref flag showElectricsInMenu 1 global elec::clearAndBuildElectricMenu
  49. # To add the list of key-bindings to the bottom of the electric menu (these are
  50. # the items you may edit with 'Config->Special Keys', which are used to
  51. # trigger Completions, Expansions, Template Stop movement etc), click this
  52. # box||To remove the list of key-bindings from the electric menu, once 
  53. # you've learnt them all, click this box.
  54. newPref flag showElectricKeysInMenu 1 global elec::clearAndBuildElectricMenu
  55. # To add a couple of menu items to let you create or delete new templates,
  56. # click this box||To remove the menu items to create/delete templates, click
  57. # this box.
  58. newPref flag addTemplateManipulators 0 global elec::clearAndBuildElectricMenu
  59. # To put all the templates into the main electric menu rather than in a 
  60. # submenu, click this box||To place all templates in a sub-menu of the 
  61. # electric menu, click this box.
  62. newPref flag putTemplatesInMainMenu 0 global elec::clearAndBuildElectricMenu
  63.  
  64. proc elec::BindingsChanged {} {
  65.     global showElectricKeysInMenu
  66.     if {$showElectricKeysInMenu} {elec::clearAndBuildElectricMenu}
  67. }
  68.  
  69. proc elec::getMenuBindings {} {
  70.     global showElectricKeysInMenu keys::specialBindings
  71.     # get menu items which represent the current bindings
  72.     if {$showElectricKeysInMenu} {
  73.     return [menu::bindingsFromArray keys::specialBindings]
  74.     } else {
  75.     return ""
  76.     }
  77. }
  78.  
  79. ## 
  80.  # -------------------------------------------------------------------------
  81.  # 
  82.  # "elec::rebuildElectricMenu" --
  83.  # 
  84.  #  Reasonably clever procedure to construct a Template menu from the
  85.  #  ${mode}electrics array on the fly.  Works with 'ensemble' completions,
  86.  #  putting them in submenus (that's why the code is a little messy; I
  87.  #  couldn't dream up a neater method).
  88.  # -------------------------------------------------------------------------
  89.  ##
  90. proc elec::rebuildElectricMenu {args} {
  91.     set mmode [modeALike]
  92.     if {[cache::exists elecMenu::elec-${mmode}]} {
  93.     cache::read elecMenu::elec-${mmode}
  94.     message ""
  95.     } else {        
  96.     global ${mmode}electrics electricMenu showElectricsInMenu
  97.     
  98.     set m [list Menu -n ${electricMenu} -m -p elec::MenuProc]
  99.     # make the menu of electrics if desired
  100.     if {$showElectricsInMenu && [array exists ${mmode}electrics]} {
  101.         set items [lsort [array names ${mmode}electrics]]
  102.         # remove all contractions
  103.         set items [lremove -all -glob $items "*'*"]
  104.         # remove something else (I've forgotten what!)
  105.         regsub -all { [^ ]*\*[^ ]*} " $items " { } items
  106.         set c [set items]
  107.         while {[regexp {\{(\w+) \w+\}} $c all pref]} {
  108.         set c [string range $c [expr {[string last "\{$pref " $c] +2}] end]
  109.         lappend got $pref
  110.         }
  111.         if {[info exists got]} {
  112.         foreach pref $got {
  113.             regsub "(\{${pref} \\w+\} )+" $items \
  114.               "\{Menu -n \"   ${pref}\" -m -p elec::MenuProc \{\\0\}\} " items
  115.         }
  116.         }    
  117.     } else {
  118.         set items ""
  119.     }
  120.     # make the whole menu
  121.     set items [concat [elec::makeTemplatesMenu $mmode] $items "(-" \
  122.       [elec::getMenuBindings] [list "Add Electric Item"] ]
  123.     global addTemplateManipulators
  124.     if {$addTemplateManipulators} {
  125.         lappend items "Grab Selection" "Insert Old Selection" \
  126.           "Insert In Lines"
  127.     }
  128.     lappend items "Clear Elec Menu Cache"
  129.     lappend m $items
  130.     cache::add elecMenu::elec-${mmode} variable m
  131.     }
  132.     eval $m
  133. }
  134.  
  135. proc elec::clearAndBuildElectricMenu {args} {
  136.     cache::deletePat elecMenu::elec-*
  137.     elec::rebuildElectricMenu
  138. }
  139.  
  140. proc elec::makeTemplatesMenu {mmode} {
  141.     # make the templates submenu
  142.     global ${mmode}Templates elec::MenuTemplates \
  143.       elec::LicenseTemplates menu::additions putTemplatesInMainMenu
  144.     set m ${elec::MenuTemplates}
  145.     if {[info exists ${mmode}Templates]} {
  146.     set m [concat $m [set ${mmode}Templates]]
  147.     }
  148.     set m [lsort $m]
  149.     eval lappend m "(-" [lsort [lremove ${elec::LicenseTemplates} "none"]]
  150.     if {[info exists menu::additions(elec)]} {
  151.     foreach i [set menu::additions(elec)] {
  152.         eval lappend m "(-" [lrange $i 2 end]
  153.     }
  154.     }
  155.     lappend m "(-" "addTemplateItem" "removeTemplateItem"
  156.     if {$putTemplatesInMainMenu} {
  157.     foreach i $m {
  158.         if {[lindex $i 0] == "Menu"} {
  159.         lappend ret $i
  160.         } else {
  161.         lappend ret "[quote::Prettify $i] "
  162.         }
  163.     }
  164.     return $ret
  165.     } else {    
  166.     return [list "Menu -n Templates -p elec::userTemplates [list $m]"]
  167.     }
  168.     
  169. }
  170.  
  171. proc elec::rebuildTemplatesMenu { {mmode ""} } {
  172.     if {$mmode == ""} {set mmode [modeALike]}
  173.     eval [lindex [elec::makeTemplatesMenu $mmode] 0]
  174. }
  175.  
  176. proc elec::userTemplates {menu item} {
  177.     set t [file::$item]    
  178.     if {$t != ""} {
  179.     elec::Insertion $t
  180.     }
  181. }
  182.  
  183. proc elec::MenuProc {menu item} {
  184.     switch -- $item {
  185.     "Next Stop Or Indent" {bind::IndentOrNextstop}
  186.     "Prev Stop" { ring::- }
  187.     "nth Stop" {ring::nth}
  188.     "Complete" {bind::Completion}
  189.     "Complete Or Tab" {bind::TabOrComplete}
  190.     "Expand" {bind::Expansion}
  191.     "Next Stop" {ring::+}
  192.     "Real Tab" {insertActualTab}
  193.     "Add Electric Item" {elec::AddItem}
  194.     "Grab Selection" {elec::GrabSelection}
  195.     "Insert Old Selection" {elec::InsertOldSelection}
  196.     "Insert In Lines" {elec::InsertInLines}
  197.     "Clear All Stops" {ring::clear}
  198.     "Clear Elec Menu Cache" {elec::clearAndBuildElectricMenu}
  199.     default {
  200.         if {[regexp {(.*) $} $item "" item]} {
  201.         set item [join $item ""]
  202.         elec::userTemplates $menu \
  203.           [string tolower [string index $item 0]][string range $item 1 end]
  204.         } else {
  205.         insertText $item
  206.         bind::Completion
  207.         }
  208.     }
  209.     }
  210. }
  211.  
  212. proc elec::AddItem {} {
  213.     global mode
  214.     if {$mode == ""} { beep ; message "No mode set…" ; return }
  215.     global ${mode}electrics
  216.     set e [prompt "Enter the electric item for '$mode' mode:" ""]
  217.     if {$e == ""} {return}
  218.     set default [file::_varValue ${mode}electrics($e)]
  219.     #[file::_getDefault "Do you want to start with this as the template?"]
  220.     set value [getline "Enter the electric extension, using •prompt•, \\r \\\{, \\\} etc" $default]
  221.     if {$value != ""} {
  222.     if {[string length $value] > 210} {
  223.         alertnote "Alpha unfortunately truncates direct entry to about 200 characters, however you can add directly to arrdefs.tcl"
  224.     }
  225.     eval set ${mode}electrics($e) \"$value\"
  226.     addArrDef ${mode}electrics $e [set ${mode}electrics($e)]
  227.     cache::deletePat elecMenu::elec-[modeALike]
  228.     elec::rebuildElectricMenu
  229.     }
  230. }
  231.  
  232. proc file::addTemplateItem {} {
  233.     global elec::MenuTemplates mode
  234.     global ${mode}Templates
  235.     set v elec::MenuTemplates
  236.     set v [expr {$mode != "" && [dialog::yesno \
  237.       "Is this item '$mode' mode-specific (otherwise I'll make it global)?"] \
  238.       ? "${mode}Templates" : "elec::MenuTemplates"}]
  239.     set e [join [prompt "Enter the new template menu item name:" ""] ""]
  240.     if {$e == ""} {return}
  241.     set e [string tolower [string index $e 0]][string range $e 1 end]
  242.     set default [file::_getDefault "Do you want to start with this as the template?" t]
  243.     set t "\r"
  244.     append t "proc file::${e} \{\} \{\r"
  245.     append t "\t# You must fill this in\r"
  246.     append t $default
  247.     append t "\r\r\telec::Insertion \$t\r\}\r"
  248.     addUserLine $t
  249.     lappend $v $e
  250.     lappend modifiedVars $v
  251.     elec::rebuildTemplatesMenu
  252.     regsub -all "\r" $default ";" default
  253.     append default { elec::Insertion $t}
  254.     ;proc file::$e {} $default
  255.     elec::clearAndBuildElectricMenu
  256.     if {[dialog::yesno "I've added a template for the procedure to your 'prefs.tcl'. Do you want to edit it now?"]} {
  257.     global::editPrefsFile
  258.     goto [maxPos]
  259.     }
  260.     return ""
  261. }
  262.  
  263. proc file::removeTemplateItem {} {
  264.     global elec::MenuTemplates mode
  265.     global ${mode}Templates
  266.     global modifiedVars
  267.     set tlist ${elec::MenuTemplates}
  268.     catch {set tlist [concat $tlist [set ${mode}Templates]]}
  269.     set l [listpick -p "Which template shall I permanently remove?" \
  270.       [lsort $tlist]]
  271.     if {[set i [lsearch -exact ${elec::MenuTemplates} $l]] != -1} {
  272.     set elec::MenuTemplates [lreplace ${elec::MenuTemplates} $i $i]
  273.     lappend modifiedVars elec::MenuTemplates
  274.     } else {
  275.     set i [lsearch -exact [set ${mode}Templates] $l]
  276.     set ${mode}Templates [lreplace [set ${mode}Templates] $i $i]
  277.     lappend modifiedVars ${mode}Templates
  278.     }
  279.     elec::rebuildTemplatesMenu
  280.     elec::clearAndBuildElectricMenu
  281.     global::editPrefsFile
  282.     set pat "\rproc\[ \t\]+file::"
  283.     append pat $l
  284.     append pat "\[ \t\]+\{\[ \t\]*\}\[ \t\]\{(\r\[^\}\].*)*\r\}\r"
  285.     while 1 {
  286.     set fpos [search -f 1 -r 1 -n $pat 0]
  287.     if {[llength $fpos] == 0} {
  288.         break
  289.     }
  290.     eval deleteText $fpos
  291.     }
  292.     while 1 {
  293.     set fpos [search -f 1 -r 1 -n "^(\r\r|\n\n)" 0]
  294.     if {[llength $fpos] == 0} {
  295.         break
  296.     }
  297.     eval replaceText $fpos "\r"
  298.     }
  299.     save
  300.     return ""
  301. }
  302.  
  303.  
  304. # procedures below get added to the menu if you set the 'poweruser' flag
  305. # in "elecBindings.tcl".  They make it easy to create large template 
  306. # procedures 
  307. proc elec::GrabSelection {} {
  308.     global __elec::grabbed
  309.     set __elec::grabbed [getSelect]
  310. }
  311.  
  312. proc elec::InsertOldSelection {} {
  313.     global __elec::grabbed
  314.     insertText [quote::Insert [set __elec::grabbed]]
  315. }
  316.  
  317. proc elec::InsertInLines {} {
  318.     global __elec::grabbed
  319.     insertText [elec::_MakeIntoInsertion ${__elec::grabbed}]
  320. }
  321.  
  322. proc elec::_MakeIntoInsertion {t {var "t"}} {
  323.     if {$t == ""} { return $t }
  324.     regsub -all "\n" $t "\r" t
  325.     while 1 {
  326.     set ret [string first "\r" $t]
  327.     if { $ret == -1 } { set ret [string length $t] }
  328.     append b [string range $t 0 $ret]
  329.     if {[string length $b] > 20} {
  330.         while 1 {
  331.         append a "\tappend $var \"[quote::Insert [string range $b 0 59]]\"\r"
  332.         if {[set b [string range $b 60 end]] == ""} {
  333.             break
  334.         }
  335.         }
  336.     }
  337.     set t [string range $t [incr ret] end]
  338.     if {[string length $t] == 0} { 
  339.         if {$b != ""} {
  340.         append a "\tappend $var \"$b\"\r"
  341.         }
  342.         break 
  343.     }
  344.     }
  345.     return $a
  346. }
  347.  
  348.  
  349.  
  350.  
  351.